package toy.keli.picmap;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.model.LatLngBounds;
import com.baidu.mapsdkexample.geometry.markercluster.MyItem;
import com.baidu.mapsdkexample.util.clusterutil.clustering.Cluster;
import com.baidu.mapsdkexample.util.clusterutil.clustering.ClusterManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import toy.keli.picmap.model.Model;
import toy.keli.picmap.model.def;
import toy.keli.picmap.model.event;
import toy.keli.picmap.model.log;
import toy.keli.picmap.model.map;
import toy.keli.picmap.model.pic;
import toy.keli.picmap.model.system;
import toy.keli.picmap.model.types.MapPosIn;
import toy.keli.picmap.tools.Control;
import toy.keli.picmap.tools.Filter;
import toy.keli.picmap.tools.Location;
import toy.keli.picmap.tools.Progress;
import toy.keli.picmap.tools.Search;
import toy.keli.picmap.tools.Share;
import toy.keli.picmap.tools.Show;
import toy.keli.picmap.tools.StatusBar;
import toy.keli.picmap.util.utilArray;
import toy.keli.picmap.util.utilKeyboard;
import toy.keli.picmap.util.utilStore;

import static toy.keli.picmap.BmapActivity.callActiveType.Pic;

/**
 * 点聚合地图
 */
public class BmapActivity extends BaseActivity {

    private static final String TAG = BmapActivity.class.getSimpleName();

    // 地图View实例
    public MapView mMapView;
    private Button mButton;
    private BaiduMap mBaiduMap;

    public ClusterManager<MyItem> mClusterManager;
    //加载结束事件对外扩展用的
    boolean LoadOver=false;
    //配置类
    public Control config;
    //配置项弹框
    public Dialog configDialog;
    //进程id
    int pid=0;
    //搜索关键字
    public String searchKey;

    /**
     * 界面被创建事件
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bmap);

        log.debug("create..");
        //ServiceManager.listServices();
        //定义一个setting记录APP是几次启动！！！  Android判断程序是否第一次启动   https://www.jb51.net/article/109558.htm
        SharedPreferences setting = getSharedPreferences("toy.keli.picmap", 0);
        Boolean user_first = setting.getBoolean("FIRST", true);
        if (user_first) {// 第一次则跳转到欢迎页面
            setting.edit().putBoolean("FIRST", false).commit();
            this.ConfirmDialog("欢迎使用","似乎是第一次运行这个程序，是否初始化图片数据？(左下角按钮默认单击打开目录页，双击定位，长按配置项，其中单击可在配置项目自定义)",()->{
                startActivity(new Intent(this, ConfigActivity.class));
            });
            return ;
        }

        Intent intent = getIntent();
        String pidStr=intent.getStringExtra("pid");

        pid = pidStr==null ? 0: Integer.valueOf(pidStr);
        mMapView = findViewById(R.id.mapview);
        mButton = findViewById(R.id.filter);
        mBaiduMap = mMapView.getMap();
        config=Control.create(this,mMapView,mBaiduMap);
        //全屏显示
        if(config.fullScreenEnable) system.setStatusBarFullTransparent(this.getWindow());
        //展示类初始化
        Show.mBaiduMap=mBaiduMap;
        Show.act=this;
        //公共存储目录配置
        utilStore.fileRoot=this.getFilesDir()+"/";
        //如果是分享的pmr文件打开 载入这个包的信息
        if(intent.getData()!=null) {
            String p = intent.getData().getPath();
            this.getShare().packageOpen(p);
        }
        //初始化试图
        initView();
        //尝试更新图片
        this.getProgressBar().tryAutoUpdatePic();
    }

    ////其他组件
    //进度条
    public Progress getProgressBar(){
        return (Progress)__get(Progress.class);
    }
    //分享
    public Share getShare(){
        return (Share)__get(Share.class);
    }
    //过滤器
    public Filter getFilter(){
        return (Filter)__get(Filter.class);
    }
    //搜索
    public Search getSearch(){
        return (Search)__get(Search.class);
    }
    //状态栏
    public StatusBar getStatusbar(){ return (StatusBar)__get(StatusBar.class);}

    //给其他组件提供的 配置按钮图标的文字
    public void setmButtonIco(String ico) {
        if(mButton.getText().equals(ico)) return;
        mButton.setText(ico);
        //mButton.setBackgroundResource(R.drawable.custom_change_btn);
        mButton.getBackground().setAlpha((" ⏸▶️".indexOf(ico)>0) ?0:255);
    }

    /**
     * 返回按钮事件处理
     */
    @Override
    public void onBackPressed() {
        //返回先关闭动画
        if(Show.getTimeAnimation(false)!=null) {
            config.resetDateFilter();
            Show.clearTimeAnimation();
        }else {
            super.onBackPressed();
        }
    }

    /**
     * 重新绘制事件
     */
    @Override
    protected void onResume() {
        super.onResume();
        if (null != mMapView) {
            mMapView.onResume();
        }
       // onCreate(null);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (null != mMapView) {
            mMapView.onPause();
        }
    }

    /**
     * 退出应用事件
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != mMapView) {
            mMapView.onDestroy();
        }
    }
    /**
     * 初始化试图中 配置按钮单击事件
     * @param view
     */
    private boolean timerClick = false;
    private int clickNum = 0;
    private void initView() {
        BmapActivity self = this;
        mButton.getBackground().setAlpha(200);
        findViewById(R.id.map_search).setVisibility(View.VISIBLE);
        findViewById(R.id.titleBar).setVisibility(View.GONE);
        findViewById(R.id.date_pick1).setVisibility(View.GONE);
        //按钮的单击事件
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //log.Info("onbutton click ok");
                clickNum++;
                if (!timerClick)
                    timerClick = new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            if (clickNum == 1) {
                                OnConfigClick(view);
                            } else {
                                //定位当前位置
                                OnConfigDbClick(null);
                            }
                            timerClick = false;
                            clickNum = 0;
                        }
                    }, 300);    //延时300执行
            }
        });
        //按钮的长按事件 固定配置页展示
        mButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                OnConfigLongClick(v);
                return true;
            }
        });
        //如果按钮是不可以移动的则添加 按钮的滑动事件
        if(!Control.bmoveEnable) {
//            event.bindTouch(mButton,(t)->{
//                OnConfigTouch(t);
//            });
        }
        //搜索框获取焦点事件 失去焦点的时候就隐藏搜索组件
        findViewById(R.id.map_search).setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(!hasFocus) v.setVisibility(View.GONE);
            }
        });

        ////分享按钮
        Button shareButton = (Button) findViewById(R.id.share);
        //返回按钮
        findViewById(R.id.go_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        //分享按钮的单击事件绑定
        shareButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getShare().packageShare(mItemsFilter,true);
            }
        });
        //分享按钮的长按事件绑定
        shareButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return OnShareLongClick(v);
            }
        });
        //地图加载完成时间 做些初始化操作
        mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {
            @Override
            public void onMapLoaded() {
                // 添加marker
                initCluster();
                HashMap<String, Double> p = map.getPostion(self.pid);
                // 设置初始中心
                LatLng center = new LatLng(p.get("y"), p.get("x"));
                //是否开启动画
                if (config.animationEnable) {
                    Show.zoomTo(center, p.get("z").floatValue(), () -> {
                        addMarkers();
                        LoadOver = true;
                    });
                }else {
                    MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(center, p.get("z").floatValue());
                    mBaiduMap.setMapStatus(mapStatusUpdate);
                    LoadOver = true;
                    addMarkers();
                }

                //比例尺所在位置修正
                if (config.scaleEnable) {
                    Point point = system.getScreenSize(BmapActivity.this);
                    point.y = 60;
                    point.x -= 150;
                    mMapView.setScaleControlPosition(point);
                }
                //按钮可移动状态下位置修正 按钮可移动支持
                config.Postion("but_add",mButton);
                //按钮可移动的实现
                if(Control.bmoveEnable) {
                    event.canDrag(mButton, mMapView.getWidth(), mMapView.getHeight(),(v)->{
                        config.Postion("but_add",v.getLeft(),v.getTop());
                    });
                }
                //应用加载完成调用
                if(mOnLoadOver!=null) mOnLoadOver.call();
            }
        });

        ////百度地图的一些事件
        //地图加载完成之后添加点信息
        mBaiduMap.setOnMapRenderValidDataListener(new BaiduMap.OnMapRenderValidDataListener() {
            @Override
            public void onMapRenderValidData(boolean b, int i, String s) {
                log.debug("onMapRenderValidData");
                if (LoadOver) addMarkers();
            }
        });
        //地图位置偏移重新加载坐标信息
        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
            private float pressX;
            private float pressY;

            @Override
            public void onTouch(MotionEvent event) {
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    //按下
                    case MotionEvent.ACTION_DOWN:
                        pressX = event.getX();
                        pressY = event.getY();
                        break;
                    case MotionEvent.ACTION_UP:  //松开
                        if (Math.abs(event.getX() - pressX) + Math.abs(event.getY() - pressY) > 200)
                            addMarkers();
                }
            }
        });
        //地图点的长按事件出现右键弹框
        mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
            InfoWindow point=null;
            @Override
            public void onMapLongClick(LatLng latLng) {
                Log.d("kdebug","长按");
                Button button = new Button(getApplicationContext());
                button.setPadding(10,0,0,10);
                button.setBackgroundResource(R.drawable.popup);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mBaiduMap.hideInfoWindow();
                    }
                });
                button.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        systemCopy(String.valueOf(button.getText()));
                        mBaiduMap.hideInfoWindow();
                        return true;
                    }
                });
                Location.PointToAddr(latLng,(addr)-> {
                    button.setText(addr);
                    point=(InfoWindow)new InfoWindow(button,latLng,0);
                    mBaiduMap.showInfoWindow(point);
                    self.getSearch().openPointMenu(button,latLng);
                });
            }
        });
    }
    ////定义事件
    //分享按钮长按
    private boolean OnShareLongClick(View v) {
        popupMenu(v, new String[]{"筛选", "原图"}, (name) -> {
            switch (name) {
                case "原图":
                    getShare().packageShare(mItemsFilter, false);
                    break;
                case "筛选":
                    openPics(null,"share");
            }
        });
        return false;
    }
    //按钮滑动
    void OnConfigTouch(event.type t){
            if(Show.getTimeAnimation(false)!=null){
                Show.onEvent(t);
                return;
            }
            switch (t){
                case LEFT:
                    startActivity(new Intent(this, ConfigActivity.class));
                    break;
                case RIGHT:
                    Control.date=new long[]{};
                    Show.getTimeAnimation().toggleTaRuning();
                    break;
                case UP:
                    config.dateFilter(mButton);
                    break;
                case DOWN:
                    this.setSearchEnabled(true);
                default:
            }
    }
    //按钮单击
    public void OnConfigClick(View view){
        if(Show.getTimeAnimation(false)!=null){
            Show.onEvent(event.type.CLICK);
            return;
        }
        switch (Control.locationClick){
            case 0:
                startActivity(new Intent(this, ConfigActivity.class));
                break;
            case 1:
                onLocationDo(null);
                break;
            case 2:
                OnConfigLongClick(view);
                break;
            case 3:
                config.dateFilter(view);
                break;
            case 4:
                break;
            default:
                String[] items = new String[]{"图片","消费记录","声音","文字","视频"};
                popupMenu(view,items,(title)->{
                    switch (title){
                        case "图片":
                        case "声音":
                        case "文字":
                        case "视频":
                            break;
                        case "消费记录":
                        case "6分钟的屏幕copy":
                        case "名片":
                        case "链接":
                    }
                });
        }
    }
    //按钮双击 默认定位
    public void OnConfigDbClick(View view){
        onLocationDo(null);
    }
    //按钮的长按事件 默认是配置信息展示
    public void OnConfigLongClick(View view){
        Log.d("kdebug","configOnLongClick");
        config.show();
    }


    /**LocationListener
     * 获取当前地址
     */
    LatLng nowPoint;
    @SuppressLint("NewApi")
    public void onLocationDo(Location.callback func){
        mBaiduMap.setMyLocationEnabled(true);   //定位后的点
        if(!getPermission(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.READ_EXTERNAL_STORAGE)) return;
        Location tl = new Location(this);
        if(func==null) func=(location)->{
            if(tl.mLocation!=null){
                Show.moveTo(tl.mLocation.getLongitude(),tl.mLocation.getLatitude());
                nowPoint=new LatLng(tl.mLocation.getLatitude(),tl.mLocation.getLongitude());
            }
        };
        tl.addToolsLocation(mMapView,func);
    }


    public void openPic(int id) {
        Intent intent = new Intent(BmapActivity.this, PicActivity.class);
        //关于Android Activity之间传递数据的6种方式  https://www.jb51.net/article/108903.htm
        intent.putExtra("id",""+id);
        startActivity(intent);
    }

    public void openPics(int[] ids,String type) {
        if(ids==null){
            ids=new int[mItemsFilter.size()]; int i=0;
            for(MyItem it:mItemsFilter){
                ids[i++]=it.id;
            }
        }
        Intent intent = new Intent(BmapActivity.this, PicActivity.class);
        intent.putExtra("id", utilArray.idzip(ids));
        intent.putExtra("type", type);
        if(type.equals("share"))
            startActivityForResult(intent, Pic.ordinal());
        else
            startActivity(intent);
    }

    /**
     *  页面从其他页面重新载入事件
     */
    //调用activity返回的类型
    protected enum callActiveType {Pic,Conf};
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (callActiveType.values()[requestCode]){
            //图片的时候 需要分享的化
            case Pic:
                if(data.getIntArrayExtra("ids")==null) break;
                int[] ids = data.getIntArrayExtra("ids");
                boolean rarDo = ! data.getBooleanExtra("firsthand",true);
                List<MyItem> itemsFilter=new ArrayList<MyItem>();
                for(MyItem it:mItems){
                    if(utilArray.indexOf(ids, it.id)>-1){
                        itemsFilter.add(it);
                    }
                }
                getShare().packageShare(itemsFilter, rarDo);
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + callActiveType.values()[requestCode]);
        }
    }

    //初始化点聚合信息
    private void initCluster() {
        // 定义点聚合管理类ClusterManager
        mClusterManager = new ClusterManager<MyItem>(this, mBaiduMap);
        mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
        mBaiduMap.setOnMarkerClickListener(mClusterManager);
        //合并的点单击
        mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyItem>() {
            @Override
            public boolean onClusterClick(Cluster<MyItem> cluster) {
                int[] ids=new int[cluster.getSize()]; int n=0;
                for(MyItem it:cluster.getItems()){
                    ids[n++]=it.id;
                }
                LatLng pos = cluster.getPosition();
                openPics(ids,"open");
                return false;
            }
        });
        //单独的点单击
        mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
            @Override
            public boolean onClusterItemClick(MyItem item) {
                Show.thumbnail(item);
                //openPic(item.id);
//                        Toast.makeText(BmapActivity.this, "点击单个Item", Toast.LENGTH_SHORT).show();
                return false;
            }
        });
    }

    //刷新地图
    public void refresh(){
        MapStatus status = mBaiduMap.getMapStatus();
        if(status.target==null) return;
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(status.target,status.zoom+1);
        mBaiduMap.setMapStatus(mapStatusUpdate);

        mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(status.target,status.zoom);
        mBaiduMap.setMapStatus(mapStatusUpdate);
    }

    //设置搜索可用
    public void setSearchEnabled(boolean b){
        findViewById(R.id.titleBar).setVisibility(b?View.VISIBLE:View.GONE);
        if(b){
            TextView inBox=findViewById(R.id.poi);
            inBox.requestFocus();
            InputMethodManager imm = (InputMethodManager)
                    getSystemService(INPUT_METHOD_SERVICE);
            imm.showSoftInput(inBox, InputMethodManager.SHOW_IMPLICIT);
            utilKeyboard.setOnVisibilityListener(inBox,(bv)->{
                if(!bv) setSearchEnabled(false);
            });
        }
    }

    ////坐标点信息
    //集合(图片的id)
    HashSet<Integer> sites = new HashSet<Integer>();
    //向地图添加Marker点
    public List<MyItem> mItems=new ArrayList<MyItem>();
    //share组件会用到这个变量用于存储需要分享的图片
    public List<MyItem> mItemsFilter=new ArrayList<MyItem>();
    //是否可以添加坐标点
    boolean canAddMarker=true;
    public void setCanAddMarker(boolean canAddMarker) {
        this.canAddMarker = canAddMarker;
    }
    //添加坐标点
    public void addMarkers() {
        if(!canAddMarker) return;
        if(!config.picShowEnable){
            mClusterManager.clearItems();
            refresh();
            return;
        }
        MapPosIn pos = new MapPosIn();
        MapStatus status = mBaiduMap.getMapStatus();
        LatLngBounds b = status.bound;
        pos.range= new double[]{b.southwest.longitude, b.northeast.longitude, b.southwest.latitude, b.northeast.latitude};
        pos.pid=pid;
        pos.key=searchKey;
        List<MyItem> items=new ArrayList<MyItem>();
        // 添加Marker点
//        LatLng llA = new LatLng(22.527225, 114.06153);
//        items.add(new MyItem(llA));
//        mClusterManager.addItems(items);
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (def v : map.getPoints(pos)) {
                    pic p=(pic)Model.populateRecord(pic.class,v);
                    LatLng ll = new LatLng(p.y,p.x);
                    if(!sites.contains(p.id)) {
                        MyItem it = new MyItem(ll, v);
                        items.add(it);
                        mItems.add(it);
                        sites.add(p.id);
                    }
                }

                //mClusterManager.clearItems();
                if(items.size()>0 && mClusterManager!=null)
                    mClusterManager.addItems(items);
                Log.d("kdebug","call addmarkers:"+items.size());
                refresh();
            }
        }).start();
    }

    //对其他界面抛出的事件 share界面用到了
    callback mOnLoadOver;
    public void registerOnLoadOver(callback o) {
        mOnLoadOver=o;
    }
}